home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Graphics Programming (2nd Edition)
/
Visual Basic Graphics Programming 2nd Edition.iso
/
Src
/
Ch10
/
FlakeAn1.frm
(
.txt
)
< prev
next >
Wrap
Visual Basic Form
|
1999-06-08
|
8KB
|
246 lines
VERSION 5.00
Begin VB.Form frmFlakeAn1
Caption = "FlakeAn1"
ClientHeight = 4335
ClientLeft = 2280
ClientTop = 900
ClientWidth = 5070
LinkTopic = "Form1"
PaletteMode = 1 'UseZOrder
ScaleHeight = 4335
ScaleWidth = 5070
Begin VB.TextBox txtTheta
Height = 285
Left = 600
MaxLength = 3
TabIndex = 1
Text = "60"
Top = 360
Width = 375
End
Begin VB.TextBox txtDepth
Height = 285
Left = 600
MaxLength = 3
TabIndex = 0
Text = "3"
Top = 0
Width = 375
End
Begin VB.PictureBox picCanvas
AutoRedraw = -1 'True
Height = 4335
Left = 1080
ScaleHeight = 285
ScaleMode = 3 'Pixel
ScaleWidth = 261
TabIndex = 4
Top = 0
Width = 3975
End
Begin VB.CommandButton cmdGo
Caption = "Go"
Default = -1 'True
Height = 375
Left = 240
TabIndex = 2
Top = 840
Width = 615
End
Begin VB.Label Label1
Caption = "Theta"
Height = 255
Index = 1
Left = 0
TabIndex = 5
Top = 360
Width = 495
End
Begin VB.Label Label1
Caption = "Depth"
Height = 255
Index = 0
Left = 0
TabIndex = 3
Top = 0
Width = 495
End
Attribute VB_Name = "frmFlakeAn1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private Const PI = 3.14159
' Coordinates of the points in the initiator.
Private Const NUM_INITIATOR_POINTS = 3
Private InitiatorX(0 To NUM_INITIATOR_POINTS) As Single
Private InitiatorY(0 To NUM_INITIATOR_POINTS) As Single
' Angles and distances for the generator.
Private Const NUM_GENERATOR_ANGLES = 4
Private ScaleFactor As Single
Private GeneratorDTheta(1 To NUM_GENERATOR_ANGLES) As Single
' Draw the complete snowflake.
Private Sub DrawFlake(ByVal depth As Integer, ByVal length As Single, ByVal offset As Single)
Dim i As Integer
Dim x1 As Single
Dim y1 As Single
Dim x2 As Single
Dim y2 As Single
Dim dx As Single
Dim dy As Single
Dim theta As Single
picCanvas.Cls
' Draw the snowflake.
For i = 1 To NUM_INITIATOR_POINTS
x1 = InitiatorX(i - 1)
y1 = InitiatorY(i - 1)
x2 = InitiatorX(i)
y2 = InitiatorY(i)
dx = x2 - x1
dy = y2 - y1
theta = ATan2(dy, dx)
DrawFlakeEdge depth, x1, y1, _
theta, length, offset
Next i
End Sub
' Draw the animation frames.
Private Sub MakeMovie(ByVal depth As Integer, ByVal length As Single)
Const FRAMES_PER_DEPTH = 20
Const MS_PER_FRAME = 50
Dim i As Integer
Dim max_depth As Integer
Dim offset As Single
Dim doffset As Single
Dim next_time As Long
' Draw the animation frames.
max_depth = depth
next_time = GetTickCount()
For depth = 1 To max_depth
doffset = length * ScaleFactor ^ depth * _
Sin(GeneratorDTheta(2)) / FRAMES_PER_DEPTH
offset = doffset
For i = 1 To FRAMES_PER_DEPTH
WaitTill next_time
DrawFlake depth, length, offset
DoEvents
offset = offset + doffset
next_time = next_time + MS_PER_FRAME
Next i
Next depth
End Sub
Private Sub CmdGo_Click()
Dim depth As Integer
Dim length As Single
Dim theta As Single
Dim unit As Single
Dim vunit As Single
Dim hunit As Single
picCanvas.Cls
MousePointer = vbHourglass
DoEvents
' Get the parameters.
If Not IsNumeric(txtDepth.Text) Then txtDepth.Text = "5"
depth = CInt(txtDepth.Text)
' Initialize the generator.
If Not IsNumeric(txtTheta.Text) Then txtTheta.Text = "60"
theta = CInt(txtTheta.Text) / 180 * PI
' See how big we can make the curve.
vunit = 0.9 * picCanvas.ScaleHeight / (Sqr(3) * 4 / 3)
hunit = 0.9 * picCanvas.ScaleWidth / 2
If vunit < hunit Then
unit = vunit
Else
unit = hunit
End If
length = 2 * unit
' Initialize the generator and initiator.
InitializeGenerator theta, length
' Draw the animation frames.
MakeMovie depth, length
MousePointer = vbDefault
Beep
End Sub
' Initialize the generator for the indicated angle.
Private Sub InitializeGenerator(ByVal theta As Single, ByVal length As Single)
Dim xmid As Single
Dim ymid As Single
' Initialize the initiator's coordinates.
xmid = picCanvas.ScaleWidth / 2
ymid = picCanvas.ScaleHeight / 2
InitiatorX(1) = xmid + length / 2
InitiatorY(1) = ymid - length / 2 * Sqr(3) / 3
InitiatorX(2) = xmid - length / 2
InitiatorY(2) = InitiatorY(1)
InitiatorX(3) = xmid
InitiatorY(3) = ymid + length / 2 * Sqr(3) * 2 / 3
InitiatorX(0) = InitiatorX(3)
InitiatorY(0) = InitiatorY(3)
ScaleFactor = 1 / (2 * (1 + Cos(theta)))
GeneratorDTheta(1) = 0
GeneratorDTheta(2) = theta
GeneratorDTheta(3) = -2 * theta
GeneratorDTheta(4) = theta
End Sub
' Recursively draw a snowflake edge starting at
' (x1, y1) in direction theta and distance dist.
' Leave the coordinates of the endpoint in
' (x1, y1).
Private Sub DrawFlakeEdge(ByVal depth As Integer, ByRef x1 As Single, ByRef y1 As Single, ByVal theta As Single, ByVal dist As Single, ByVal offset As Single)
Dim status As Integer
Dim i As Integer
Dim x2 As Single
Dim y2 As Single
Dim new_theta As Single
Dim dtheta As Single
Dim hyp As Single
Dim adj As Single
If depth <= 1 Then
' Draw the final depth.
dist = dist * ScaleFactor
adj = dist * Cos(GeneratorDTheta(2))
hyp = Sqr(adj * adj + offset * offset)
x2 = x1 + dist * Cos(theta)
y2 = y1 + dist * Sin(theta)
picCanvas.Line (x1, y1)-(x2, y2)
x1 = x2
y1 = y2
dtheta = ATan2(offset, adj)
new_theta = theta + dtheta
x2 = x1 + hyp * Cos(new_theta)
y2 = y1 + hyp * Sin(new_theta)
picCanvas.Line (x1, y1)-(x2, y2)
x1 = x2
y1 = y2
new_theta = theta - dtheta
x2 = x1 + hyp * Cos(new_theta)
y2 = y1 + hyp * Sin(new_theta)
picCanvas.Line (x1, y1)-(x2, y2)
x1 = x2
y1 = y2
x2 = x1 + dist * Cos(theta)
y2 = y1 + dist * Sin(theta)
picCanvas.Line (x1, y1)-(x2, y2)
x1 = x2
y1 = y2
Exit Sub
End If
' Recursively draw the edge.
dist = dist * ScaleFactor
For i = 1 To NUM_GENERATOR_ANGLES
theta = theta + GeneratorDTheta(i)
DrawFlakeEdge depth - 1, x1, y1, theta, dist, offset
Next i
End Sub
Private Sub Form_Resize()
Dim wid As Single
' Make the picCanvas as big as possible.
wid = ScaleWidth - picCanvas.Left
If wid < 120 Then wid = 120
picCanvas.Move picCanvas.Left, 0, wid, ScaleHeight
End Sub